Linux 软中断机制分析

您所在的位置:网站首页 Linux 软中断依赖中断控制器吗 Linux 软中断机制分析

Linux 软中断机制分析

2024-07-10 03:52| 来源: 网络整理| 查看: 265

软中断分析

    最近工作繁忙,没有时间总结内核相关的一些东西。上次更新博客到了linux内核中断子系统。这次总结一下软中断,也就是softirq。之后还会总结一些tasklet、工作队列机制。

1. 为什么要软中断

    编写驱动的时候,一个中断产生之后,内核在中断处理函数中可能需要完成很多工作。但是中断处理函数的处理是关闭了中断的。也就是说在响应中断时,系统不能再次响应外部的其它中断。这样的后果会造成有可能丢失外部中断。于是,linux内核设计出了一种架构,中断函数需要处理的任务分为两部分,一部分在中断处理函数中执行,这时系统关闭中断。另外一部分在软件中断中执行,这个时候开启中断,系统可以响应外部中断。

    关于软件中断的理论各种书籍都有介绍,不多叙述。而要真正体会软件中断的作用就必须从代码的角度来分析。我们做工作时候讲求的是professional,当一个人在某个领域一无所知的时候,我们称他为小白,偶,非苹果电脑。小白的脑子里充满了各种问题。慢慢的当这些疑惑解释完之后,小白就脱白了。此时,我们对这个领域的基本框架有了解,但这和professional还有一定的差距。再加以时日,逐渐融会贯通该领域才能达到专业的境界。

2. 什么时候触发处理软件中断

    说了这么多废话,赶快步入正题。初识软中断,脑子里肯定有不少的疑问,首先就是软件中断在什么地方被触发处理?这个问题的答案就是:一个硬件中断处理完成之后。下面的函数在处理完硬件中断之后推出中断处理函数,在irq_exit中会触发软件中断的处理。

asmlinkage void __exception asm_do_IRQ(unsigned int irq, structpt_regs *regs)  {      struct pt_regs *old_regs = set_irq_regs(regs);         irq_enter();         /*       * Some hardware gives randomly wrong interrupts.  Rather       * than crashing, do something sensible.       */       if (irq >= NR_IRQS)          handle_bad_irq(irq, &bad_irq_desc);      else           generic_handle_irq(irq);         /* AT91 specific workaround */       irq_finish(irq);         irq_exit();      set_irq_regs(old_regs);  }

    这里要注意,invoke_softirq必须满足两个条件才能被调用到,一个就是不是在硬件中断处理过程中或者在软件中断处理中,第二个就是必须有软件中断处于pending状态。第二个好理解,有软件中断产生才去处理,没有就不处理。第一个就不好理解了。

/*  * Exit an interrupt context. Process softirqs if needed and possible: */   void irq_exit(void)  {      account_system_vtime(current);      trace_hardirq_exit();      sub_preempt_count(IRQ_EXIT_OFFSET);      if (!in_interrupt() && local_softirq_pending())          invoke_softirq();     #ifdef CONFIG_NO_HZ      /* Make sure that timer wheel updates are propagated */       rcu_irq_exit();      if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched())          tick_nohz_stop_sched_tick(0);  #endif       preempt_enable_no_resched();  }

在linux系统的进程数据结构里,有这么一个数据结构

#define preempt_count() (current_thread_info()->preempt_count),

利用preempt_count可以表示是否处于中断处理或者软件中断处理过程中。

#define PREEMPT_MASK    (__IRQ_MASK(PREEMPT_BITS)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3